/***************************************************************************//**
 * @file	 csa37f7x_flash.h
 * @version  V1.0.0
 * @author	 Chipsea MCU Group
 * @date	 2020-10-21
 * @brief	 该文件包含FLASH各功能参数的定义和函数接口声明
 * 
 * @copyright Copyright (C) 2020 Chipsea Technologies Corp. All rights reserved.
 ****************************************************************************
 * @attention
 *	硬件平台: CSA37F70 评估板V1.0 \n
 *	SDK版本：  CSA37F7X_SDK_1.0.0
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date 	   <th>Version	<th>Author	  <th>Description
 * <tr><td>2020/10/21  <td>1.0.0		<td>Chipsea MCU Group	<td>创建初始版本
 * </table>
 *
 *****************************************************************************/
#ifndef __CSA37F7X_FLASH_H__
#define __CSA37F7X_FLASH_H__

// Include external header file.
#include "csa37f7x.h"
#include "csa37f7x_system.h"

#ifdef __cplusplus
extern "C" {
#endif

/** @addtogroup FLASH 内存控制器(FMC)
  CSA37FX70 内嵌 64K 字节片上 FLASH，分别为 60KB 应用程序内存(APROM)和 4KB 在系统编程
(ISP) 空间(LDROM)，可以通过 ISP 更新。当芯片焊到 PCB 板子上以后，In System Programming (ISP) 
功能使用户能更新应用程序内存。芯片上电以后，Cortex-M0 CPU 从 APROM 还是 LDROM 取代码运
行，取决于用户配置区 Config0 中启动选项(CBS)的设置。<br>

###特性：
    - 高达 24MHz 的零等待连续地址读访问
    - 60KB 应用程序存储空间(APROM)
    - 4KB 在系统编程 (ISP) 空间(LDROM)
    - 所有内部 Flash 页擦除单位为 512 字节
    - 在系统编程(ISP)/在应用编程(IAP)用于更新片上 Flash EPROM
    - 支持空片调试，代码选项值为全 FFFF 时按默认值读入
    - 用户配置区写时硬件自动写反码，防止用户误写，读正反码检查<br>
    
###地址编码及寻找范围：
*  \image html cpu_flash_addr_left.png 
  @{
*/


/**
* @brief Flash ISP编程时钟频率
*/
#ifdef __CSA37F70__
typedef enum
{
    ISP_Freq_48MHz = 0x00,
    ISP_Freq_24MHz = 0x01,
    ISP_Freq_12MHz = 0x02,
    ISP_Freq_8MHz = 0x03,
    ISP_Freq_6MHz = 0x04,
    ISP_Freq_4MHz = 0x05,
    ISP_Freq_2MHz = 0x06,
    ISP_Freq_1MHz = 0x07,

}flash_freq_t;
#else
typedef enum
{
    /*CSA37F71不支持48MHz*/
    ISP_Freq_24MHz = 0x01,  /*!<24MHz */
    ISP_Freq_12MHz = 0x02,  /*!<12MHz */
    ISP_Freq_8MHz = 0x03,   /*!<8MHz */
    ISP_Freq_6MHz = 0x04,   /*!<6MHz */
    ISP_Freq_4MHz = 0x05,   /*!<4MHz */
    ISP_Freq_2MHz = 0x06,   /*!<2MHz */
    ISP_Freq_1MHz = 0x07,   /*!<1MHz */

}flash_freq_t;
#endif

/**
* @brief Flash 启动位置
*/
typedef enum
{
    FMC_APROM = 0x00,	/*!<由 APROM启动 */
    FMC_LDROM = 0x01,	/*!<由 LDROM启动 */
    FMC_SRAM = 0x02,	/*!<由 SRAM启动 */

} flash_rom_mode_t;

/**
* @brief Flash 配置参数结构体定义
*/
typedef struct
{
    flash_freq_t isp_freq;					/*!<Flash ISP编程参考时钟频率档位选择，默认 ISP_Freq_8MHz */	
    enable_state_t enter_deepstandby_en;	/*!<Flash 进入deepstandby使能信号，1：退出deepstandby模式；0：进入deepstandby模式 */	
    enable_state_t ldrom_update_en;			/*!<Flash LDROM更新使能控制，1：LDROM可以被更新.；0：LDROM不能被更新*/	
    enable_state_t cfg_update_en;			/*!<Flash 用户配置区更新使能控制，1：使能配置区更新；0：禁止配置区更新 */	
    enable_state_t aprom_update_en;			/*!<Flash APROM更新使能控制，1：APROM可以被更新；0：APROM不能被更新 */	
} flash_config_t;


/**
* @brief 宏定义检查Flash ISP 编程时钟频率
*/
#ifdef __CSA37F70__
#define FLASH_ISP_FREQ_CHECK(value)		(((value) == ISP_Freq_48MHz)||\
										((value) == ISP_Freq_24MHz)||\
										((value) == ISP_Freq_12MHz)||\
										((value) == ISP_Freq_8MHz)||\
										((value) == ISP_Freq_6MHz)||\
										((value) == ISP_Freq_4MHz)||\
										((value) == ISP_Freq_2MHz)||\
										((value) == ISP_Freq_1MHz))
#else
#define FLASH_ISP_FREQ_CHECK(value)		(((value) == ISP_Freq_24MHz)||\
										((value) == ISP_Freq_12MHz)||\
										((value) == ISP_Freq_8MHz)||\
										((value) == ISP_Freq_6MHz)||\
										((value) == ISP_Freq_4MHz)||\
										((value) == ISP_Freq_2MHz)||\
										((value) == ISP_Freq_1MHz))

#endif


/**
* @brief 宏定义检查Flash 启动位置
*/
#define FLASH_ROM_SWITCH_CHECK(value)	(((value) == FMC_APROM)||\
										((value) == FMC_LDROM)||\
										((value) == FMC_SRAM))


/**@brief		FLASH功能初始化
 *
 * @param[in]	ptr_config		输入FLASH初始化结构体
 * @return		无
*/
void flash_init (flash_config_t* ptr_config);

/**@brief		Flash 页擦除
 *
 * @param[in]	adr		擦除页起始地址
 * @return		返回结果，1：成功；0：失败
*/
error_status_t flash_page_erase (uint32_t adr);

/**@brief		Flash 多页擦除
 *
 * @param[in]	adr 	擦除页起始地址
  * @param[in]	num 	擦除页个数
 * @return		返回结果，1：成功；0：失败
*/
error_status_t flash_more_page_erase(uint32_t adr, uint8_t num);

/**@brief		Flash 页写入
 *
 * @param[in]	adr 	页起始地址
 * @param[in]	sz 		写入数据大小
 * @param[in]	buf 	写入数据buf指针值
 * @return		返回结果，1：成功；0：失败
*/
error_status_t flash_page_write (uint32_t adr, uint16_t sz, uint8_t *buf);

/**@brief		Flash 页读取
 *
 * @param[in]	adr 	页起始地址
 * @param[in]	sz		读取数据大小
 * @param[in]	buf 	读取数据存放buf指针值
 * @return		返回结果，1：成功；0：失败
*/
error_status_t flash_page_read (uint32_t adr, uint16_t sz, uint8_t *buf);

/**@brief		Flash 启动位置选择
 *
 * @param[in]	rom_mode 	启动位置选择
 * @return		无
*/
void flash_rom_switch(flash_rom_mode_t rom_mode);


/*@}*/ /* end of group FLASH */


#ifdef __cplusplus
}
#endif

#endif  //__CSA37F7X_FLASH_H__


/*** (C) COPYRIGHT 2020 Chipsea Technologies (Shenzhen) Corp. ***/
